package com.seeyon.apps.brwh.kit;

import okhttp3.*;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.*;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.HttpEntity;
import org.apache.http.cookie.Cookie;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.JSON;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class HttpKit {

    private static PoolingHttpClientConnectionManager cm;

    private static void init() {
        if (cm == null) {
            cm = new PoolingHttpClientConnectionManager();
            cm.setMaxTotal(50);// 整个连接池最大连接数
            cm.setDefaultMaxPerRoute(5);// 每路由最大连接数，默认值是2
        }
    }

    /**
     * 发送POST请求
     *
     * @param url     请求的URL
     * @param headers 请求的头部参数
     * @param json    请求的JSON数据
     * @return 返回请求结果
     * @throws Exception 异常信息
     */
    public static String post(String url, Map<String, Object> headers, String json) throws Exception {
        HttpPost httpPost = new HttpPost(url);
        if (!headers.isEmpty()) {
            for (Map.Entry<String, Object> param : headers.entrySet()) {
                httpPost.addHeader(param.getKey(), String.valueOf(param.getValue()));
            }
        }
        StringEntity entity = new StringEntity(json, "UTF-8");
        entity.setContentEncoding("utf-8");
        entity.setContentType("application/json");
        httpPost.setEntity(entity);
        return getResult(httpPost);
    }


    /**
     * x-www-form-urlencoded    POST
     * @param url
     * @param headers
     * @param dataMap
     * @return
     * @throws Exception
     */
    public static String postUrlencoded(String url, Map<String, Object> headers, Map<String,Object> dataMap) throws Exception {
//        OkHttpClient client = new OkHttpClient().newBuilder()
//                .build();
//        MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
//        RequestBody body = RequestBody.create();
//
//
//        Request request = new Request.Builder()
//                .url(url)
//                .method("POST", body)
//                .addHeader("Content-Type", "application/x-www-form-urlencoded")
//                .build();
//        if(headers != null){
//            for (String value : headers.keySet()) {
//                request.header(value,StrKit.str(headers.get(value)));
//            }
//        }
//
//
//        Response response = client.newCall(request).execute();
//        String string = response.body().string();
        HttpPost httpPost = new HttpPost(url);
        if (!headers.isEmpty()) {
            for (Map.Entry<String, Object> param : headers.entrySet()) {
                httpPost.addHeader(param.getKey(), String.valueOf(param.getValue()));
            }
        }
        // 创建参数列表
        List<NameValuePair> params = new ArrayList<>();
        for (String value : dataMap.keySet()) {
            params.add(new BasicNameValuePair(value, StrKit.str(dataMap.get(value))));
        }
        // 设置参数到请求为application/x-www-form-urlencoded
        UrlEncodedFormEntity urlEncodedFormEntity = new UrlEncodedFormEntity(params, "UTF-8");
        httpPost.setEntity(urlEncodedFormEntity);
        return getResult(httpPost);
    }

    /**
     * 用于进行HTTP PATCH请求的辅助方法
     *
     * @param url     请求的URL
     * @param headers 请求的头部参数
     * @param json    请求的JSON数据
     * @return 请求的结果
     * @throws Exception 异常情况
     */
    public static String patch(String url, Map<String, Object> headers, String json) throws Exception {
        HttpPatch httpPatch = new HttpPatch(url);
        if (!headers.isEmpty()) {
            for (Map.Entry<String, Object> param : headers.entrySet()) {
                httpPatch.addHeader(param.getKey(), String.valueOf(param.getValue()));
            }
        }
        StringEntity entity = new StringEntity(json, "UTF-8");
        entity.setContentEncoding("utf-8");
        entity.setContentType("application/json");
        httpPatch.setEntity(entity);
        return getResult(httpPatch);
    }


    /**
     * 获取登录cookie
     *
     * @param url 登录的URL地址
     * @return 登录的cookie
     * @throws Exception
     */
    public static String postCookie(String url) throws Exception {
        // 创建参数Map对象
        Map<String, Object> paramMap = new LinkedHashMap<String, Object>();
        paramMap.put("CompanyDB", SapKit.getSapTestCompanyDB());
        paramMap.put("UserName", SapKit.getSapTestUserName());
        paramMap.put("Password", SapKit.getSapTestPassword());
        paramMap.put("Languahe", SapKit.getSapTestLanguahe());
        // 将参数Map对象转换为JSON字符串
        String json = JSON.toJSONString(paramMap);

        // 创建Http POST请求对象
        HttpPost httpPost = new HttpPost(url);
        // 创建请求体对象，并设置请求体内容和内容类型
        StringEntity entity = new StringEntity(json, "UTF-8");
        entity.setContentType("application/json");
        httpPost.setEntity(entity);

        // 执行HTTP请求并获取cookie结果
        return getCookieResult(httpPost);
    }


    public static String get(String url, Map<String, Object> headers) throws Exception {
        // 创建一个HttpGet对象并传入url参数
        HttpGet httpGet = new HttpGet(url);
        // 如果headers参数不为空
        if (!headers.isEmpty()) {
            // 遍历headers参数的每个键值对
            for (Map.Entry<String, Object> param : headers.entrySet()) {
                // 向httpGet对象添加Header参数，键为param的键，值为param的值的字符串形式
                httpGet.addHeader(param.getKey(), String.valueOf(param.getValue()));
            }
        }
        // 调用getResult方法并返回结果
        return getResult(httpGet);
    }


    /**
     * 处理Http请求
     *
     * @param request HTTP请求对象
     * @return 请求结果
     * @throws Exception 抛出异常
     */
    private static String getResult(HttpRequestBase request) throws Exception {
        CloseableHttpClient httpClient = getHttpClient();
        CloseableHttpResponse response = httpClient.execute(request);
        HttpEntity entity = response.getEntity();
        if (entity != null) {
            String result = EntityUtils.toString(entity, "UTF-8");//主数据接口 乱码 加响应编码
            response.close();
            return result;
        }
        return "";
    }


    /**
     * 通过连接池获取HttpClient
     *
     * @return 返回通过连接池获取的HttpClient
     */
    private static CloseableHttpClient getHttpClient() {
        init();
        BasicCookieStore cookieStore = new BasicCookieStore();
        return HttpClients.custom().setDefaultCookieStore(cookieStore).setConnectionManager(cm).build();
    }

    private static String getCookieResult(HttpRequestBase request) throws Exception {
        // 初始化操作
        init();

        // 创建Cookie存储对象
        BasicCookieStore cookieStore = new BasicCookieStore();

        // 创建HttpClient对象并设置默认CookieStore
        CloseableHttpClient httpClient = HttpClients.custom().setDefaultCookieStore(cookieStore).build();

        // 执行HTTP请求
        CloseableHttpResponse response = httpClient.execute(request);

        // 获取响应实体
        HttpEntity entity = response.getEntity();

        // 响应实体为空时返回空字符串
        String B1SESSION = "";
        if (entity != null) {
            // 将响应实体内容转换为字符串（使用UTF-8编码）
            String result = EntityUtils.toString(entity, "UTF-8");

            // 将字符串转换为JSON对象
            JSONObject obj = JSONObject.parseObject(result);

            // 如果响应结果中包含SessionId，则将其保存到B1SESSION变量
            if (obj.containsKey("SessionId")) {
                B1SESSION = obj.getString("SessionId");
            }

            // 关闭响应
            response.close();
        }

        // 如果B1SESSION为空，则返回空字符串
        if ("".equals(B1SESSION)) {
            return "";
        }

        // 创建存储请求Cookie的列表
        List<String> reqCookieList = new ArrayList<String>();

        // 将B1SESSION添加到请求Cookie列表中
        reqCookieList.add("B1SESSION=" + B1SESSION);

        // 获取CookieStore中的Cookie列表
        List<Cookie> cookieList = cookieStore.getCookies();

        // 遍历Cookie列表，将每个Cookie的名称和值添加到请求Cookie列表中
        for (Cookie cookie : cookieList) {
            cookie.getName();
            cookie.getValue();
            reqCookieList.add(cookie.getName() + "=" + cookie.getValue());
        }

        // 将请求Cookie列表以分号分隔的形式拼接成字符串
        String cookie = StringUtils.join(reqCookieList, ";");

        // 返回请求Cookie字符串
        return cookie;
    }

}
